package com.common.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

/**
 * @author 大静
 * @version 1.0
 * @date 2021-05-07 10:51
 * @description 动态生成图片
 */
public class VerifyCode {
  // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}
  private static final String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"};
  // 可选字符
  // "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
  private static final String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
  //    背景色
  private final Color bgColor = new Color(255, 255, 255);
  //    基数（一个文字所占的空间大小）
  private final int base = 30;
  //    图像宽度
  private final int width = base * 5;
  //    图像高度
  private final int height = base;
  //    文字个数
  private final int len = 4;
  //    字体大小
  private final int fontSize = 22;
  //    验证码上的文本
  private String text;

  private BufferedImage bufferedImage = null;
  private Graphics2D graphics2D = null;
  /** 生成验证码图片 */
  public void drawImage(OutputStream outputStream) {
    // 1.创建图片缓冲区对象, 并设置宽高和图像类型
    bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    // 2.得到绘制环境
    graphics2D = (Graphics2D) bufferedImage.getGraphics();
    // 3.开始画图，设置背景色
    graphics2D.setColor(bgColor);
    graphics2D.fillRect(0, 0, width, height);
    // 用来装载验证码上的文本
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < len; i++) {
      // 设置画笔颜色 -- 随机
      graphics2D.setColor(new Color(getRandom(0, 150), getRandom(0, 150), getRandom(0, 150)));
      //      设置字体
      graphics2D.setFont(new Font(fontNames[getRandom(0, fontNames.length)], Font.BOLD, fontSize));
      //      旋转文字
      int theta = getRandom(-45, 45);
      graphics2D.rotate(theta * Math.PI / 180, 7 + i * base, height - 8);
      //     写字
      String code = codes.charAt(getRandom(0, codes.length())) + "";
      graphics2D.drawString(code, 7 + i * base, height - 8);
      sb.append(code);
      graphics2D.rotate(-theta * Math.PI / 180, 7 + i * base, height - 8);
    }
    this.text = sb.toString();

    // 画干扰线
    for (int i = 0; i < len; i++) {
      // 设置画笔颜色 -- 随机
      graphics2D.setColor(new Color(getRandom(0, 150), getRandom(0, 150), getRandom(0, 150)));
      graphics2D.drawLine(getRandom(0, 120), getRandom(0, 30), getRandom(0, 120), getRandom(0, 30));
    }
    // 4.保存图片到指定的输出流
    try {
      ImageIO.write(this.bufferedImage, "jpeg", outputStream);
    } catch (IOException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    } finally {
      //      释放资源
      graphics2D.dispose();
    }
  }

  /**
   * 获取验证码字符串
   *
   * @return 验证码对应的字符串
   */
  public String getCode() {
    return this.text;
  }
  /*
   * 生成随机数的方法
   */
  private static int getRandom(int start, int end) {
    Random random = new Random();
    return random.nextInt(end - start) + start;
  }
}
